﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Collections;
using System.Windows;
using Microsoft.VisualStudio.Modeling.Diagrams;

namespace devtm.AutoMapper
{


    public class MapperContainer : TreeViewItem
    {


        static byte[] imgClass162 = devtm.AutoMapper.Properties.Resources.Class162.GetBytes();
        static byte[] imgNamespace = devtm.AutoMapper.Properties.Resources.Namespace.GetBytes();
        static byte[] imgMapper = devtm.AutoMapper.Properties.Resources.fleche.GetBytes();

        private TypeElement source;
        private Mapper mapper;


        #region Ctor

        public MapperContainer()
        {

            Items.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", System.ComponentModel.ListSortDirection.Ascending));

        }

        public MapperContainer(string[] @namespace, int index, TypeElement source)
            : this()
        {            

            if (index >= @namespace.Length)
            {
                this.index = index;
                Name = source.Name;
                ContextTitle = new ContainerHeader() { Label = Name, ImageSource = imgClass162 };
                Header = new HeaderCtrl() { Context = ContextTitle };

                this.source = source;

                RefreshMappers();

            }
            else
            {

                Name = @namespace[index];
                ContextTitle = new ContainerHeader() { Label = Name, ImageSource = imgNamespace };
                Header = new HeaderCtrl() { Context = ContextTitle };

                index++;
                MapperContainer cc = new MapperContainer(@namespace, index, source);
                AddChild(cc);

            }

        }

        public MapperContainer(Mapper mapper)
            : this()
        {
            this.mapper = mapper;
            Name = mapper.Name;
            ContextTitle = new ContainerHeader() { Label = Name, ImageSource = imgMapper };
            Header = new HeaderCtrl() { Context = ContextTitle };
        }

        #endregion


        private void RefreshMappers()
        {

            foreach (MappingSource item in source.SMappings)
            {
                MapperContainer cc = new MapperContainer(item.Mapper);
                AddChild(cc);
            }
        }

        internal MapperContainer GetItem(TypeElement source)
        {

            string Namespace = source.Namespace;

            foreach (MapperContainer item in this.Items)
            {

                MapperContainer i = item.GetItem(source);
                if (i != null)
                    return i;

            }

            return null;

        }

        internal MapperContainer GetNamespace(string[] nn1, ref int index, TypeElement source)
        {
            string n = nn1[index];
            MapperContainer retour = null;

            foreach (MapperContainer item in this.Items)
                if ((item.Name as string) == n)
                {
                    index++;
                    if (index < nn1.Length)
                    {
                        MapperContainer r2 = item.GetNamespace(nn1, ref index, source);
                        if (r2 != null)
                        {
                            retour = r2;
                            break;
                        }
                    }
                }

            if (retour == null)
                retour = this;

            return retour;

        }

        internal void Insert(string[] @namespace, int index, TypeElement source)
        {
            MapperContainer retour = this;

            if (index < @namespace.Length)
            {
                string n = @namespace[index];

                foreach (MapperContainer item in this.Items)
                    if ((item.Name as string) == n)
                    {
                        index++;
                        if (index < @namespace.Length)
                        {
                            retour = item.GetNamespace(@namespace, ref index, source);
                            break;
                        }
                    }
            }

            MapperContainer nn = new MapperContainer(@namespace, index, source);
            retour.AddChild(nn);

        }

        //internal string Name { get; set; }

        internal ContainerHeader ContextTitle { get; set; }


        protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (source != null)
                ContextTitle.Label = Name = source.Name;

            if (mapper != null)
                ContextTitle.Label = Name = mapper.Name;

        }
       

        protected override void OnSelected(System.Windows.RoutedEventArgs e)
        {
            base.OnSelected(e);

            if (mapper != null)
                SelectMapper();

            else if (source != null)
                SelectSource();



        }

        private void SelectSource()
        {

            ModelDetailExplorer model = GetParent<ModelDetailExplorer>();

            TypeElementShape mm = PresentationViewsSubject.GetPresentation(source).FirstOrDefault() as TypeElementShape;

            if (mm != null)            
                SelectShape(mm);
            
            //if (model != null)
            //    model.Liste.DataContext = new BoxMapper(mapper);

        }

        private void SelectMapper()
        {
            ModelDetailExplorer model = GetParent<ModelDetailExplorer>();

            MapperShape mm = PresentationViewsSubject.GetPresentation(mapper).FirstOrDefault() as MapperShape;
            if (mm != null)            
                SelectShape(mm);            

            //if (model != null)
            //    model.Liste.DataContext = new BoxMapper(mapper);
        }

        private static void SelectShape(NodeShape mm)
        {

            try
            {

                Microsoft.VisualStudio.Modeling.Diagrams.Diagram diagram = mm.Diagram;

                if (diagram != null)
                {

                    DiagramView diagramClientView = diagram.ActiveDiagramView;

                    if ((diagramClientView != null))
                    {

                        var aa = new DiagramItem(mm);

                        if (mm.CanFocus)
                            diagramClientView.Selection.FocusedItem = aa;

                        diagramClientView.DiagramClientView.EnsureVisible(mm.AbsoluteBoundingBox, mm.EnsureVisiblePreference);
                        diagramClientView.Selection.Set(diagramClientView.Selection.FocusedItem);

                    }

                }

            }
            catch (Exception)
            { }

        }

        private IServiceProvider GetService()
        {

            TreeViewItem i = this.Parent as TreeViewItem;
            while(i is MapperContainer)
            {
                i = i.Parent as TreeViewItem;
            }

            return (i as MapperContainers).ServiceProvider;

        }

        private T GetParent<T>()
            where T : FrameworkElement
        {


            FrameworkElement i = this.Parent as FrameworkElement;

            while (!(i is T) && i != null)         
                i = i.Parent as FrameworkElement;
                
            return i as T;

        }



        public int index { get; set; }
    }

}
